{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n",
      "/home/leon/miniconda3/lib/python3.6/importlib/_bootstrap.py:219: RuntimeWarning: compiletime version 3.5 of module 'tensorflow.python.framework.fast_tensor_util' does not match runtime version 3.6\n",
      "  return f(*args, **kwds)\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "from keras.models import Model\n",
    "from keras.layers import Input\n",
    "from keras.layers.recurrent import SimpleRNN, LSTM, GRU\n",
    "from keras.layers.wrappers import Bidirectional\n",
    "from keras import backend as K\n",
    "import json\n",
    "from collections import OrderedDict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def format_decimal(arr, places=6):\n",
    "    return [round(x * 10**places) / 10**places for x in arr]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "DATA = OrderedDict()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Bidirectional"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[wrappers.Bidirectional.0] merge_mode='sum', wrap a SimpleRNN layer with units=4, activation='tanh', return_sequences=False**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "random_seed = 1000\n",
    "data_in_shape = (3, 6)\n",
    "\n",
    "layer_0 = Input(shape=data_in_shape)\n",
    "layer_1 = Bidirectional(SimpleRNN(4, activation='tanh', return_sequences=False), merge_mode='sum')(layer_0)\n",
    "model = Model(inputs=layer_0, outputs=layer_1)\n",
    "\n",
    "np.random.seed(random_seed)\n",
    "data_in = 2 * np.random.random(data_in_shape) - 1\n",
    "\n",
    "# set weights to random (use seed for reproducibility)\n",
    "weights = []\n",
    "for i, w in enumerate(model.get_weights()):\n",
    "    np.random.seed(random_seed + i)\n",
    "    weights.append(2 * np.random.random(w.shape) - 1)\n",
    "model.set_weights(weights)\n",
    "\n",
    "result = model.predict(np.array([data_in]))\n",
    "data_out_shape = result[0].shape\n",
    "data_in_formatted = format_decimal(data_in.ravel().tolist())\n",
    "data_out_formatted = format_decimal(result[0].ravel().tolist())\n",
    "\n",
    "DATA['wrappers.Bidirectional.0'] = {\n",
    "    'input': {'data': data_in_formatted, 'shape': data_in_shape},\n",
    "    'weights': [{'data': format_decimal(w.ravel().tolist()), 'shape': w.shape} for w in weights],\n",
    "    'expected': {'data': data_out_formatted, 'shape': data_out_shape}\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[wrappers.Bidirectional.1] merge_mode='mul', wrap a SimpleRNN layer with units=4, activation='tanh', return_sequences=False**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "random_seed = 1001\n",
    "data_in_shape = (3, 6)\n",
    "\n",
    "layer_0 = Input(shape=data_in_shape)\n",
    "layer_1 = Bidirectional(SimpleRNN(4, activation='tanh', return_sequences=False), merge_mode='mul')(layer_0)\n",
    "model = Model(inputs=layer_0, outputs=layer_1)\n",
    "\n",
    "np.random.seed(random_seed)\n",
    "data_in = 2 * np.random.random(data_in_shape) - 1\n",
    "\n",
    "# set weights to random (use seed for reproducibility)\n",
    "weights = []\n",
    "for i, w in enumerate(model.get_weights()):\n",
    "    np.random.seed(random_seed + i)\n",
    "    weights.append(2 * np.random.random(w.shape) - 1)\n",
    "model.set_weights(weights)\n",
    "\n",
    "result = model.predict(np.array([data_in]))\n",
    "data_out_shape = result[0].shape\n",
    "data_in_formatted = format_decimal(data_in.ravel().tolist())\n",
    "data_out_formatted = format_decimal(result[0].ravel().tolist())\n",
    "\n",
    "DATA['wrappers.Bidirectional.1'] = {\n",
    "    'input': {'data': data_in_formatted, 'shape': data_in_shape},\n",
    "    'weights': [{'data': format_decimal(w.ravel().tolist()), 'shape': w.shape} for w in weights],\n",
    "    'expected': {'data': data_out_formatted, 'shape': data_out_shape}\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[wrappers.Bidirectional.2] merge_mode='concat', wrap a SimpleRNN layer with units=4, activation='tanh', return_sequences=False**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "random_seed = 1002\n",
    "data_in_shape = (3, 6)\n",
    "\n",
    "layer_0 = Input(shape=data_in_shape)\n",
    "layer_1 = Bidirectional(SimpleRNN(4, activation='tanh', return_sequences=False), merge_mode='concat')(layer_0)\n",
    "model = Model(inputs=layer_0, outputs=layer_1)\n",
    "\n",
    "np.random.seed(random_seed)\n",
    "data_in = 2 * np.random.random(data_in_shape) - 1\n",
    "\n",
    "# set weights to random (use seed for reproducibility)\n",
    "weights = []\n",
    "for i, w in enumerate(model.get_weights()):\n",
    "    np.random.seed(random_seed + i)\n",
    "    weights.append(2 * np.random.random(w.shape) - 1)\n",
    "model.set_weights(weights)\n",
    "\n",
    "result = model.predict(np.array([data_in]))\n",
    "data_out_shape = result[0].shape\n",
    "data_in_formatted = format_decimal(data_in.ravel().tolist())\n",
    "data_out_formatted = format_decimal(result[0].ravel().tolist())\n",
    "\n",
    "DATA['wrappers.Bidirectional.2'] = {\n",
    "    'input': {'data': data_in_formatted, 'shape': data_in_shape},\n",
    "    'weights': [{'data': format_decimal(w.ravel().tolist()), 'shape': w.shape} for w in weights],\n",
    "    'expected': {'data': data_out_formatted, 'shape': data_out_shape}\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[wrappers.Bidirectional.3] merge_mode='ave', wrap a SimpleRNN layer with units=4, activation='tanh', return_sequences=False**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "random_seed = 1003\n",
    "data_in_shape = (3, 6)\n",
    "\n",
    "layer_0 = Input(shape=data_in_shape)\n",
    "layer_1 = Bidirectional(SimpleRNN(4, activation='tanh', return_sequences=False), merge_mode='ave')(layer_0)\n",
    "model = Model(inputs=layer_0, outputs=layer_1)\n",
    "\n",
    "np.random.seed(random_seed)\n",
    "data_in = 2 * np.random.random(data_in_shape) - 1\n",
    "\n",
    "# set weights to random (use seed for reproducibility)\n",
    "weights = []\n",
    "for i, w in enumerate(model.get_weights()):\n",
    "    np.random.seed(random_seed + i)\n",
    "    weights.append(2 * np.random.random(w.shape) - 1)\n",
    "model.set_weights(weights)\n",
    "\n",
    "result = model.predict(np.array([data_in]))\n",
    "data_out_shape = result[0].shape\n",
    "data_in_formatted = format_decimal(data_in.ravel().tolist())\n",
    "data_out_formatted = format_decimal(result[0].ravel().tolist())\n",
    "\n",
    "DATA['wrappers.Bidirectional.3'] = {\n",
    "    'input': {'data': data_in_formatted, 'shape': data_in_shape},\n",
    "    'weights': [{'data': format_decimal(w.ravel().tolist()), 'shape': w.shape} for w in weights],\n",
    "    'expected': {'data': data_out_formatted, 'shape': data_out_shape}\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[wrappers.Bidirectional.4] merge_mode='concat', wrap a SimpleRNN layer with units=4, activation='tanh', return_sequences=True**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "random_seed = 1004\n",
    "data_in_shape = (3, 6)\n",
    "\n",
    "layer_0 = Input(shape=data_in_shape)\n",
    "layer_1 = Bidirectional(SimpleRNN(4, activation='tanh', return_sequences=True), merge_mode='concat')(layer_0)\n",
    "model = Model(inputs=layer_0, outputs=layer_1)\n",
    "\n",
    "np.random.seed(random_seed)\n",
    "data_in = 2 * np.random.random(data_in_shape) - 1\n",
    "\n",
    "# set weights to random (use seed for reproducibility)\n",
    "weights = []\n",
    "for i, w in enumerate(model.get_weights()):\n",
    "    np.random.seed(random_seed + i)\n",
    "    weights.append(2 * np.random.random(w.shape) - 1)\n",
    "model.set_weights(weights)\n",
    "\n",
    "result = model.predict(np.array([data_in]))\n",
    "data_out_shape = result[0].shape\n",
    "data_in_formatted = format_decimal(data_in.ravel().tolist())\n",
    "data_out_formatted = format_decimal(result[0].ravel().tolist())\n",
    "\n",
    "DATA['wrappers.Bidirectional.4'] = {\n",
    "    'input': {'data': data_in_formatted, 'shape': data_in_shape},\n",
    "    'weights': [{'data': format_decimal(w.ravel().tolist()), 'shape': w.shape} for w in weights],\n",
    "    'expected': {'data': data_out_formatted, 'shape': data_out_shape}\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[wrappers.Bidirectional.5] merge_mode='concat', wrap a GRU layer with units=4, activation='tanh', recurrent_activation='hard_sigmoid', return_sequences=True**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "random_seed = 1005\n",
    "data_in_shape = (3, 6)\n",
    "\n",
    "layer_0 = Input(shape=data_in_shape)\n",
    "layer_1 = Bidirectional(GRU(4, activation='tanh', recurrent_activation='hard_sigmoid', return_sequences=True), merge_mode='concat')(layer_0)\n",
    "model = Model(inputs=layer_0, outputs=layer_1)\n",
    "\n",
    "np.random.seed(random_seed)\n",
    "data_in = 2 * np.random.random(data_in_shape) - 1\n",
    "\n",
    "# set weights to random (use seed for reproducibility)\n",
    "weights = []\n",
    "for i, w in enumerate(model.get_weights()):\n",
    "    np.random.seed(random_seed + i)\n",
    "    weights.append(2 * np.random.random(w.shape) - 1)\n",
    "model.set_weights(weights)\n",
    "\n",
    "result = model.predict(np.array([data_in]))\n",
    "data_out_shape = result[0].shape\n",
    "data_in_formatted = format_decimal(data_in.ravel().tolist())\n",
    "data_out_formatted = format_decimal(result[0].ravel().tolist())\n",
    "\n",
    "DATA['wrappers.Bidirectional.5'] = {\n",
    "    'input': {'data': data_in_formatted, 'shape': data_in_shape},\n",
    "    'weights': [{'data': format_decimal(w.ravel().tolist()), 'shape': w.shape} for w in weights],\n",
    "    'expected': {'data': data_out_formatted, 'shape': data_out_shape}\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[wrappers.Bidirectional.6] merge_mode='concat', wrap a LSTM layer with units=4, activation='tanh', recurrent_activation='hard_sigmoid', return_sequences=True**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "random_seed = 1006\n",
    "data_in_shape = (3, 6)\n",
    "\n",
    "layer_0 = Input(shape=data_in_shape)\n",
    "layer_1 = Bidirectional(LSTM(4, activation='tanh', recurrent_activation='hard_sigmoid', return_sequences=True), merge_mode='concat')(layer_0)\n",
    "model = Model(inputs=layer_0, outputs=layer_1)\n",
    "\n",
    "np.random.seed(random_seed)\n",
    "data_in = 2 * np.random.random(data_in_shape) - 1\n",
    "\n",
    "# set weights to random (use seed for reproducibility)\n",
    "weights = []\n",
    "for i, w in enumerate(model.get_weights()):\n",
    "    np.random.seed(random_seed + i)\n",
    "    weights.append(2 * np.random.random(w.shape) - 1)\n",
    "model.set_weights(weights)\n",
    "\n",
    "result = model.predict(np.array([data_in]))\n",
    "data_out_shape = result[0].shape\n",
    "data_in_formatted = format_decimal(data_in.ravel().tolist())\n",
    "data_out_formatted = format_decimal(result[0].ravel().tolist())\n",
    "\n",
    "DATA['wrappers.Bidirectional.6'] = {\n",
    "    'input': {'data': data_in_formatted, 'shape': data_in_shape},\n",
    "    'weights': [{'data': format_decimal(w.ravel().tolist()), 'shape': w.shape} for w in weights],\n",
    "    'expected': {'data': data_out_formatted, 'shape': data_out_shape}\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[wrappers.Bidirectional.7] merge_mode='sum', wrap a SimpleRNN layer with units=4, activation='tanh', return_sequences=True**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "random_seed = 1007\n",
    "data_in_shape = (3, 6)\n",
    "\n",
    "layer_0 = Input(shape=data_in_shape)\n",
    "layer_1 = Bidirectional(SimpleRNN(4, activation='tanh', return_sequences=True), merge_mode='sum')(layer_0)\n",
    "model = Model(inputs=layer_0, outputs=layer_1)\n",
    "\n",
    "np.random.seed(random_seed)\n",
    "data_in = 2 * np.random.random(data_in_shape) - 1\n",
    "\n",
    "# set weights to random (use seed for reproducibility)\n",
    "weights = []\n",
    "for i, w in enumerate(model.get_weights()):\n",
    "    np.random.seed(random_seed + i)\n",
    "    weights.append(2 * np.random.random(w.shape) - 1)\n",
    "model.set_weights(weights)\n",
    "\n",
    "result = model.predict(np.array([data_in]))\n",
    "data_out_shape = result[0].shape\n",
    "data_in_formatted = format_decimal(data_in.ravel().tolist())\n",
    "data_out_formatted = format_decimal(result[0].ravel().tolist())\n",
    "\n",
    "DATA['wrappers.Bidirectional.7'] = {\n",
    "    'input': {'data': data_in_formatted, 'shape': data_in_shape},\n",
    "    'weights': [{'data': format_decimal(w.ravel().tolist()), 'shape': w.shape} for w in weights],\n",
    "    'expected': {'data': data_out_formatted, 'shape': data_out_shape}\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### export for Keras.js tests"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "filename = '../../../test/data/layers/wrappers/Bidirectional.json'\n",
    "if not os.path.exists(os.path.dirname(filename)):\n",
    "    os.makedirs(os.path.dirname(filename))\n",
    "with open(filename, 'w') as f:\n",
    "    json.dump(DATA, f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\"wrappers.Bidirectional.0\": {\"input\": {\"data\": [0.307179, -0.769986, 0.900566, -0.035617, 0.744949, -0.575335, -0.918581, -0.205611, -0.533736, 0.683481, -0.585835, 0.484939, -0.215692, -0.635487, 0.487079, -0.860836, 0.770674, 0.905289], \"shape\": [3, 6]}, \"weights\": [{\"data\": [0.307179, -0.769986, 0.900566, -0.035617, 0.744949, -0.575335, -0.918581, -0.205611, -0.533736, 0.683481, -0.585835, 0.484939, -0.215692, -0.635487, 0.487079, -0.860836, 0.770674, 0.905289, 0.862287, -0.169138, -0.942037, 0.964055, -0.320725, 0.413374], \"shape\": [6, 4]}, {\"data\": [-0.387536, -0.469873, -0.60788, -0.138957, -0.953773, -0.608436, -0.294389, -0.553516, 0.227044, 0.160914, 0.707135, -0.917739, -0.023651, 0.841652, -0.781796, -0.177887], \"shape\": [4, 4]}, {\"data\": [-0.742023, -0.077688, -0.167692, 0.205448], \"shape\": [4]}, {\"data\": [0.195612, -0.128132, -0.96626, 0.193375, 0.789956, 0.069255, -0.988089, 0.804359, 0.509039, -0.655792, 0.460058, -0.25375, -0.635374, -0.109318, -0.426266, -0.178438, -0.113165, -0.645789, -0.480558, -0.540853, -0.191122, 0.019685, -0.171947, -0.403521], \"shape\": [6, 4]}, {\"data\": [-0.922097, 0.712992, 0.493001, 0.727856, 0.119969, -0.839034, -0.536727, -0.515472, 0.231, 0.214218, -0.791636, -0.148304, 0.309846, 0.742779, -0.123022, 0.427583], \"shape\": [4, 4]}, {\"data\": [0.318429, -0.858397, -0.059042, 0.68597], \"shape\": [4]}], \"expected\": {\"data\": [-0.004111, 0.000207, 0.025426, 0.228592], \"shape\": [4]}}, \"wrappers.Bidirectional.1\": {\"input\": {\"data\": [-0.387536, -0.469873, -0.60788, -0.138957, -0.953773, -0.608436, -0.294389, -0.553516, 0.227044, 0.160914, 0.707135, -0.917739, -0.023651, 0.841652, -0.781796, -0.177887, -0.059746, -0.745407], \"shape\": [3, 6]}, \"weights\": [{\"data\": [-0.387536, -0.469873, -0.60788, -0.138957, -0.953773, -0.608436, -0.294389, -0.553516, 0.227044, 0.160914, 0.707135, -0.917739, -0.023651, 0.841652, -0.781796, -0.177887, -0.059746, -0.745407, 0.96471, -0.959368, 0.410972, 0.931018, -0.294509, 0.21179], \"shape\": [6, 4]}, {\"data\": [-0.742023, -0.077688, -0.167692, 0.205448, -0.633864, -0.164175, -0.731823, 0.313236, 0.613465, -0.723716, -0.299231, 0.229032, 0.102561, 0.384949, -0.90948, -0.294898], \"shape\": [4, 4]}, {\"data\": [0.195612, -0.128132, -0.96626, 0.193375], \"shape\": [4]}, {\"data\": [-0.922097, 0.712992, 0.493001, 0.727856, 0.119969, -0.839034, -0.536727, -0.515472, 0.231, 0.214218, -0.791636, -0.148304, 0.309846, 0.742779, -0.123022, 0.427583, -0.882276, 0.818571, 0.043634, 0.454859, -0.007311, -0.744895, -0.368229, 0.324805], \"shape\": [6, 4]}, {\"data\": [0.318429, -0.858397, -0.059042, 0.68597, -0.649837, -0.575506, -0.564232, -0.922183, 0.440614, -0.111226, -0.319004, 0.744745, 0.189863, -0.126804, 0.616934, -0.196828], \"shape\": [4, 4]}, {\"data\": [0.486255, -0.547151, 0.285068, 0.764711], \"shape\": [4]}], \"expected\": {\"data\": [-0.76158, 0.885202, -0.415027, 0.097648], \"shape\": [4]}}, \"wrappers.Bidirectional.2\": {\"input\": {\"data\": [-0.742023, -0.077688, -0.167692, 0.205448, -0.633864, -0.164175, -0.731823, 0.313236, 0.613465, -0.723716, -0.299231, 0.229032, 0.102561, 0.384949, -0.90948, -0.294898, -0.916217, -0.699031], \"shape\": [3, 6]}, \"weights\": [{\"data\": [-0.742023, -0.077688, -0.167692, 0.205448, -0.633864, -0.164175, -0.731823, 0.313236, 0.613465, -0.723716, -0.299231, 0.229032, 0.102561, 0.384949, -0.90948, -0.294898, -0.916217, -0.699031, -0.323329, -0.673445, 0.521949, -0.306796, -0.476018, -0.628623], \"shape\": [6, 4]}, {\"data\": [0.195612, -0.128132, -0.96626, 0.193375, 0.789956, 0.069255, -0.988089, 0.804359, 0.509039, -0.655792, 0.460058, -0.25375, -0.635374, -0.109318, -0.426266, -0.178438], \"shape\": [4, 4]}, {\"data\": [-0.922097, 0.712992, 0.493001, 0.727856], \"shape\": [4]}, {\"data\": [0.318429, -0.858397, -0.059042, 0.68597, -0.649837, -0.575506, -0.564232, -0.922183, 0.440614, -0.111226, -0.319004, 0.744745, 0.189863, -0.126804, 0.616934, -0.196828, -0.463643, -0.28664, 0.297658, 0.692912, -0.648859, -0.305725, 0.358888, 0.494721], \"shape\": [6, 4]}, {\"data\": [0.486255, -0.547151, 0.285068, 0.764711, 0.481398, 0.442527, -0.409304, 0.051033, -0.652471, 0.623918, 0.698811, -0.48696, -0.525531, -0.083229, -0.54216, -0.595979], \"shape\": [4, 4]}, {\"data\": [0.0965, 0.594443, -0.987782, 0.431322], \"shape\": [4]}], \"expected\": {\"data\": [-0.972856, 0.958892, 0.567526, 0.910881, 0.825179, 0.551098, -0.972359, -0.045084], \"shape\": [8]}}, \"wrappers.Bidirectional.3\": {\"input\": {\"data\": [0.195612, -0.128132, -0.96626, 0.193375, 0.789956, 0.069255, -0.988089, 0.804359, 0.509039, -0.655792, 0.460058, -0.25375, -0.635374, -0.109318, -0.426266, -0.178438, -0.113165, -0.645789], \"shape\": [3, 6]}, \"weights\": [{\"data\": [0.195612, -0.128132, -0.96626, 0.193375, 0.789956, 0.069255, -0.988089, 0.804359, 0.509039, -0.655792, 0.460058, -0.25375, -0.635374, -0.109318, -0.426266, -0.178438, -0.113165, -0.645789, -0.480558, -0.540853, -0.191122, 0.019685, -0.171947, -0.403521], \"shape\": [6, 4]}, {\"data\": [-0.922097, 0.712992, 0.493001, 0.727856, 0.119969, -0.839034, -0.536727, -0.515472, 0.231, 0.214218, -0.791636, -0.148304, 0.309846, 0.742779, -0.123022, 0.427583], \"shape\": [4, 4]}, {\"data\": [0.318429, -0.858397, -0.059042, 0.68597], \"shape\": [4]}, {\"data\": [0.486255, -0.547151, 0.285068, 0.764711, 0.481398, 0.442527, -0.409304, 0.051033, -0.652471, 0.623918, 0.698811, -0.48696, -0.525531, -0.083229, -0.54216, -0.595979, 0.965361, 0.961457, 0.469608, -0.18139, 0.237622, -0.841546, -0.201479, 0.210842], \"shape\": [6, 4]}, {\"data\": [0.0965, 0.594443, -0.987782, 0.431322, 0.067427, -0.470888, 0.41181, 0.052982, 0.484153, 0.136201, 0.553358, -0.655578, -0.424989, 0.031041, -0.023031, 0.913774], \"shape\": [4, 4]}, {\"data\": [0.228005, 0.859479, -0.49018, 0.232871], \"shape\": [4]}], \"expected\": {\"data\": [0.295643, 0.687002, 0.016612, 0.811835], \"shape\": [4]}}, \"wrappers.Bidirectional.4\": {\"input\": {\"data\": [-0.922097, 0.712992, 0.493001, 0.727856, 0.119969, -0.839034, -0.536727, -0.515472, 0.231, 0.214218, -0.791636, -0.148304, 0.309846, 0.742779, -0.123022, 0.427583, -0.882276, 0.818571], \"shape\": [3, 6]}, \"weights\": [{\"data\": [-0.922097, 0.712992, 0.493001, 0.727856, 0.119969, -0.839034, -0.536727, -0.515472, 0.231, 0.214218, -0.791636, -0.148304, 0.309846, 0.742779, -0.123022, 0.427583, -0.882276, 0.818571, 0.043634, 0.454859, -0.007311, -0.744895, -0.368229, 0.324805], \"shape\": [6, 4]}, {\"data\": [0.318429, -0.858397, -0.059042, 0.68597, -0.649837, -0.575506, -0.564232, -0.922183, 0.440614, -0.111226, -0.319004, 0.744745, 0.189863, -0.126804, 0.616934, -0.196828], \"shape\": [4, 4]}, {\"data\": [0.486255, -0.547151, 0.285068, 0.764711], \"shape\": [4]}, {\"data\": [0.0965, 0.594443, -0.987782, 0.431322, 0.067427, -0.470888, 0.41181, 0.052982, 0.484153, 0.136201, 0.553358, -0.655578, -0.424989, 0.031041, -0.023031, 0.913774, 0.568027, -0.978941, -0.353237, -0.297017, 0.639236, 0.391994, 0.591057, -0.833079], \"shape\": [6, 4]}, {\"data\": [0.228005, 0.859479, -0.49018, 0.232871, -0.303968, -0.799141, 0.621228, 0.850429, 0.029476, -0.583346, 0.889636, -0.128896, 0.067108, -0.1059, -0.788773, -0.559347], \"shape\": [4, 4]}, {\"data\": [0.229761, -0.670851, -0.398017, -0.453102], \"shape\": [4]}], \"expected\": {\"data\": [0.930452, -0.408144, -0.615567, -0.248505, -0.314117, -0.984858, 0.795991, -0.308001, 0.962711, -0.859154, 0.315268, 0.713347, -0.435487, -0.323933, 0.690326, 0.07984, 0.980307, -0.985147, 0.47108, 0.976686, 0.090322, 0.331629, 0.308927, -0.224722], \"shape\": [3, 8]}}, \"wrappers.Bidirectional.5\": {\"input\": {\"data\": [0.318429, -0.858397, -0.059042, 0.68597, -0.649837, -0.575506, -0.564232, -0.922183, 0.440614, -0.111226, -0.319004, 0.744745, 0.189863, -0.126804, 0.616934, -0.196828, -0.463643, -0.28664], \"shape\": [3, 6]}, \"weights\": [{\"data\": [0.318429, -0.858397, -0.059042, 0.68597, -0.649837, -0.575506, -0.564232, -0.922183, 0.440614, -0.111226, -0.319004, 0.744745, 0.189863, -0.126804, 0.616934, -0.196828, -0.463643, -0.28664, 0.297658, 0.692912, -0.648859, -0.305725, 0.358888, 0.494721, -0.949408, 0.686943, 0.186782, 0.274151, -0.81428, 0.475143, 0.172363, 0.474509, 0.169688, -0.181608, -0.280812, -0.756105, -0.715837, -0.666569, -0.813171, 0.706929, 0.651385, 0.462418, -0.124894, 0.842424, 0.144887, -0.127564, -0.425119, 0.479301, -0.136498, 0.717532, 0.774194, -0.922236, 0.811165, -0.118287, -0.850532, 0.393996, -0.901293, 0.700216, -0.54517, -0.892511, -0.756845, 0.534143, -0.276233, 0.357844, 0.0165, -0.297826, -0.68739, -0.786413, -0.770103, -0.525359, 0.576525, 0.743913], \"shape\": [6, 12]}, {\"data\": [0.486255, -0.547151, 0.285068, 0.764711, 0.481398, 0.442527, -0.409304, 0.051033, -0.652471, 0.623918, 0.698811, -0.48696, -0.525531, -0.083229, -0.54216, -0.595979, 0.965361, 0.961457, 0.469608, -0.18139, 0.237622, -0.841546, -0.201479, 0.210842, -0.099026, -0.017468, -0.270985, -0.421947, 0.990418, 0.633556, -0.46994, -0.283905, 0.339371, 0.851372, -0.963439, 0.672347, -0.592494, 0.115008, 0.77155, -0.629049, -0.284972, 0.08256, -0.526964, -0.579017, 0.048964, 0.296374, -0.503246, -0.95555], \"shape\": [4, 12]}, {\"data\": [0.0965, 0.594443, -0.987782, 0.431322, 0.067427, -0.470888, 0.41181, 0.052982, 0.484153, 0.136201, 0.553358, -0.655578], \"shape\": [12]}, {\"data\": [0.228005, 0.859479, -0.49018, 0.232871, -0.303968, -0.799141, 0.621228, 0.850429, 0.029476, -0.583346, 0.889636, -0.128896, 0.067108, -0.1059, -0.788773, -0.559347, 0.674802, 0.513275, -0.95495, -0.230976, -0.430566, 0.607782, -0.292593, -0.362274, -0.825576, 0.904458, 0.531651, 0.139053, -0.797761, 0.905804, -0.875903, 0.04377, -0.704592, 0.203555, -0.083031, 0.321316, 0.334565, 0.965166, 0.31912, 0.987618, 0.11275, 0.755438, 0.133156, -0.271605, -0.739053, 0.930942, 0.723852, -0.399546, 0.365907, 0.680404, 0.302211, 0.481088, -0.254831, -0.719056, -0.13153, 0.195489, -0.457555, -0.825431, -0.866045, -0.010333, -0.168299, 0.986557, -0.410139, 0.607414, 0.897455, -0.503628, -0.125592, -0.216501, 0.854905, 0.862831, 0.911679, 0.451035], \"shape\": [6, 12]}, {\"data\": [0.229761, -0.670851, -0.398017, -0.453102, 0.590253, 0.096484, -0.035974, 0.69389, -0.260438, 0.250677, -0.193674, 0.385879, -0.991763, -0.558061, -0.750891, 0.265556, 0.657619, -0.801723, -0.910484, 0.975926, 0.288351, -0.364498, -0.126447, 0.616925, 0.303193, -0.820024, 0.429665, 0.070106, -0.34556, -0.459221, -0.798301, 0.998903, 0.359268, -0.957685, -0.915632, 0.691774, 0.25984, 0.879641, 0.179776, -0.423543, -0.867718, -0.560873, -0.382501, -0.365361, -0.723601, -0.033603, 0.789498, 0.455418], \"shape\": [4, 12]}, {\"data\": [-0.211487, -0.648815, -0.854588, -0.616238, -0.200391, -0.163753, 0.525164, 0.04282, -0.178234, 0.074889, -0.458875, -0.133347], \"shape\": [12]}], \"expected\": {\"data\": [0.465697, 0.08886, -0.10732, -0.050383, -0.103141, 0.075152, 0.369658, 0.045586, 0.419676, 0.044436, 0.681677, -0.254351, 0.378355, 0.306948, 0.048474, 0.293169, 0.628365, 0.168296, 0.332031, -0.338166, -0.279163, -0.022542, -0.184509, 0.028388], \"shape\": [3, 8]}}, \"wrappers.Bidirectional.6\": {\"input\": {\"data\": [0.486255, -0.547151, 0.285068, 0.764711, 0.481398, 0.442527, -0.409304, 0.051033, -0.652471, 0.623918, 0.698811, -0.48696, -0.525531, -0.083229, -0.54216, -0.595979, 0.965361, 0.961457], \"shape\": [3, 6]}, \"weights\": [{\"data\": [0.486255, -0.547151, 0.285068, 0.764711, 0.481398, 0.442527, -0.409304, 0.051033, -0.652471, 0.623918, 0.698811, -0.48696, -0.525531, -0.083229, -0.54216, -0.595979, 0.965361, 0.961457, 0.469608, -0.18139, 0.237622, -0.841546, -0.201479, 0.210842, -0.099026, -0.017468, -0.270985, -0.421947, 0.990418, 0.633556, -0.46994, -0.283905, 0.339371, 0.851372, -0.963439, 0.672347, -0.592494, 0.115008, 0.77155, -0.629049, -0.284972, 0.08256, -0.526964, -0.579017, 0.048964, 0.296374, -0.503246, -0.95555, -0.759658, -0.148746, 0.527992, 0.419541, -0.601167, -0.246472, 0.611566, -0.47989, -0.796678, 0.845136, -0.929013, 0.081316, -0.965527, 0.064677, 0.687209, -0.781686, 0.556524, -0.294628, 0.343468, -0.693394, -0.864068, 0.522942, -0.854592, 0.954066, 0.352462, 0.404271, 0.935993, 0.006064, -0.614327, -0.951249, -0.974544, -0.981322, -0.524456, -0.353175, -0.283883, 0.270072, 0.336334, -0.529043, 0.880513, -0.663035, -0.709319, -0.69236, 0.233949, 0.90419, -0.721928, 0.580281, -0.149192, -0.246252], \"shape\": [6, 16]}, {\"data\": [0.0965, 0.594443, -0.987782, 0.431322, 0.067427, -0.470888, 0.41181, 0.052982, 0.484153, 0.136201, 0.553358, -0.655578, -0.424989, 0.031041, -0.023031, 0.913774, 0.568027, -0.978941, -0.353237, -0.297017, 0.639236, 0.391994, 0.591057, -0.833079, 0.945585, 0.970605, 0.433942, -0.655561, -0.087023, -0.250158, 0.925941, -0.64485, 0.621258, -0.009644, -0.629281, -0.373595, 0.485602, -0.815495, 0.064045, -0.79823, 0.686509, 0.961811, -0.093605, -0.512734, -0.570547, 0.682538, 0.433208, 0.69226, 0.070745, -0.89601, -0.657133, -0.529907, -0.147531, 0.674429, 0.455914, -0.517776, -0.556739, 0.119107, 0.656276, -0.02947, 0.396705, 0.691676, 0.196748, 0.166465], \"shape\": [4, 16]}, {\"data\": [0.228005, 0.859479, -0.49018, 0.232871, -0.303968, -0.799141, 0.621228, 0.850429, 0.029476, -0.583346, 0.889636, -0.128896, 0.067108, -0.1059, -0.788773, -0.559347], \"shape\": [16]}, {\"data\": [0.229761, -0.670851, -0.398017, -0.453102, 0.590253, 0.096484, -0.035974, 0.69389, -0.260438, 0.250677, -0.193674, 0.385879, -0.991763, -0.558061, -0.750891, 0.265556, 0.657619, -0.801723, -0.910484, 0.975926, 0.288351, -0.364498, -0.126447, 0.616925, 0.303193, -0.820024, 0.429665, 0.070106, -0.34556, -0.459221, -0.798301, 0.998903, 0.359268, -0.957685, -0.915632, 0.691774, 0.25984, 0.879641, 0.179776, -0.423543, -0.867718, -0.560873, -0.382501, -0.365361, -0.723601, -0.033603, 0.789498, 0.455418, 0.827951, 0.872766, -0.595781, 0.655746, -0.100867, -0.407415, -0.5028, -0.07739, -0.432834, 0.371304, -0.410596, -0.92421, 0.688391, -0.862805, 0.206217, -0.602252, -0.132926, -0.676393, -0.280987, 0.247491, -0.027147, -0.016659, -0.23147, -0.653909, 0.876245, -0.853047, 0.6974, 0.939353, 0.068803, -0.786326, -0.10847, -0.038066, 0.594608, -0.631675, -0.052451, 0.362388, 0.573359, -0.461688, -0.799513, 0.883652, -0.681072, 0.708611, -0.103832, 0.161348, -0.938899, -0.604966, 0.588076, -0.410424], \"shape\": [6, 16]}, {\"data\": [-0.211487, -0.648815, -0.854588, -0.616238, -0.200391, -0.163753, 0.525164, 0.04282, -0.178234, 0.074889, -0.458875, -0.133347, 0.654533, -0.456294, 0.454776, -0.799519, -0.004428, 0.160632, 0.153349, -0.585922, -0.407693, 0.794725, -0.535387, 0.408942, -0.182012, 0.741361, 0.045939, -0.156736, -0.156846, -0.357358, 0.539258, 0.948017, -0.307682, -0.715505, 0.740323, 0.616044, -0.79421, 0.478351, -0.40107, 0.597915, -0.251741, -0.56835, -0.30559, 0.943538, -0.121007, -0.5726, 0.63163, -0.4633, -0.466873, -0.269675, 0.939682, -0.088032, -0.686666, -0.763883, 0.327973, -0.116397, -0.369221, 0.023515, 0.355153, 0.071139, -0.748422, -0.178133, -0.416396, -0.96893], \"shape\": [4, 16]}, {\"data\": [0.311362, -0.228519, 0.253024, -0.775634, 0.616056, -0.044226, 0.253076, 0.500853, 0.984775, 0.394826, -0.895291, -0.177992, -0.882996, 0.328019, -0.129043, 0.607012], \"shape\": [16]}], \"expected\": {\"data\": [-0.026124, 0.051784, 0.097586, 0.008106, 0.155256, 0.072258, -0.229447, -0.021167, 0.090908, 0.073529, 0.230267, 0.031812, 0.403627, -0.01663, -0.036621, 0.054221, 0.177708, -0.141792, 0.116702, 0.119188, 0.113243, 0.035616, 0.07533, 0.150966], \"shape\": [3, 8]}}, \"wrappers.Bidirectional.7\": {\"input\": {\"data\": [0.0965, 0.594443, -0.987782, 0.431322, 0.067427, -0.470888, 0.41181, 0.052982, 0.484153, 0.136201, 0.553358, -0.655578, -0.424989, 0.031041, -0.023031, 0.913774, 0.568027, -0.978941], \"shape\": [3, 6]}, \"weights\": [{\"data\": [0.0965, 0.594443, -0.987782, 0.431322, 0.067427, -0.470888, 0.41181, 0.052982, 0.484153, 0.136201, 0.553358, -0.655578, -0.424989, 0.031041, -0.023031, 0.913774, 0.568027, -0.978941, -0.353237, -0.297017, 0.639236, 0.391994, 0.591057, -0.833079], \"shape\": [6, 4]}, {\"data\": [0.228005, 0.859479, -0.49018, 0.232871, -0.303968, -0.799141, 0.621228, 0.850429, 0.029476, -0.583346, 0.889636, -0.128896, 0.067108, -0.1059, -0.788773, -0.559347], \"shape\": [4, 4]}, {\"data\": [0.229761, -0.670851, -0.398017, -0.453102], \"shape\": [4]}, {\"data\": [-0.211487, -0.648815, -0.854588, -0.616238, -0.200391, -0.163753, 0.525164, 0.04282, -0.178234, 0.074889, -0.458875, -0.133347, 0.654533, -0.456294, 0.454776, -0.799519, -0.004428, 0.160632, 0.153349, -0.585922, -0.407693, 0.794725, -0.535387, 0.408942], \"shape\": [6, 4]}, {\"data\": [0.311362, -0.228519, 0.253024, -0.775634, 0.616056, -0.044226, 0.253076, 0.500853, 0.984775, 0.394826, -0.895291, -0.177992, -0.882996, 0.328019, -0.129043, 0.607012], \"shape\": [4, 4]}, {\"data\": [-0.946541, 0.585593, -0.49527, 0.594532], \"shape\": [4]}], \"expected\": {\"data\": [-1.011799, -1.548957, 0.10959, 0.324343, 0.761706, -0.595576, -1.80914, -1.656958, -0.18263, -0.585731, -0.186718, 0.26802], \"shape\": [3, 4]}}}\n"
     ]
    }
   ],
   "source": [
    "print(json.dumps(DATA))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
